package com.boat.starter.pulsar.support;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * JDK工具
 * @author 周江
 *
 */
public class JdkUtils {
	
    /**
	 * jdk9开始（包括11），动态修改注解值会有警告，但是不影响使用。使用该方法忽略非法反射警告
	 */
    @SuppressWarnings("unchecked")
    public static void disableAccessWarnings() {
		if (!isDisabledJdk()) {
			// 不是指定jdk版本，不用执行此操作
			return;
		}
		
    	/*
    	 * jdk11下，pulsar-client的2.10.*包会有如下警告,使用此方法可以关闭告警。后续如果升级api包后，可以把这个方法取消。
    	 * WARNING: An illegal reflective access operation has occurred
    	 * WARNING: Illegal reflective access by org.apache.pulsar.common.util.netty.DnsResolverUtil (file:/D:/Users/lenovo/.m2/repository/org/apache/pulsar/pulsar-client/2.10.1/pulsar-client-2.10.1.jar) to method sun.net.InetAddressCachePolicy.get()
    	 * WARNING: Please consider reporting this to the maintainers of org.apache.pulsar.common.util.netty.DnsResolverUtil
    	 * WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
    	 * WARNING: All illegal access operations will be denied in a future release
    	 */
		try {
			Class unsafeClass = Class.forName("sun.misc.Unsafe");
			Field field = unsafeClass.getDeclaredField("theUnsafe");
			field.setAccessible(true);
			Object unsafe = field.get(null);

			Method putObjectVolatile = unsafeClass.getDeclaredMethod("putObjectVolatile", Object.class, long.class,
					Object.class);
			Method staticFieldOffset = unsafeClass.getDeclaredMethod("staticFieldOffset", Field.class);

			Class loggerClass = Class.forName("jdk.internal.module.IllegalAccessLogger");
			Field loggerField = loggerClass.getDeclaredField("logger");
			Long offset = (Long) staticFieldOffset.invoke(unsafe, loggerField);
			putObjectVolatile.invoke(unsafe, loggerClass, offset, null);
		} catch (Exception ignored) {
		}
    }
    
    /**
     * jdk9及以上版本，目前只跑在11上，暂时只用判断11
     * @return
     */
    private static boolean isDisabledJdk() {
		// 获取 jdk的标准版本 ，例如： 11, 1.8 , 1.7 , 1.6
		String jdkVersion = System.getProperty("java.specification.version");
        if("11".equals(jdkVersion)) {
        	return true;
        }
        return false;
	}
	
}
